import type { PiniaPluginContext } from 'pinia';

type DebounceOptions = {
  actions?: string[];
  wait?: number;
};

const piniaDebounce = (pluginOptions?: DebounceOptions) => {
  return (context: PiniaPluginContext) => {
    const { store, options } = context;

    const storeOptions = options.debounce || {};
    const mergedOptions = {
      ...pluginOptions,
      ...storeOptions,
    };
    const { wait = 1000, actions = [] } = mergedOptions;

    actions?.forEach((action) => {
      if (!store[action]) {
        console.warn(`Action "${action}" not found in store ${store.$id}`);
        return;
      }

      const originalAction = store[action];
      let timeoutId: ReturnType<typeof setTimeout> | null = null;

      store[action] = (...args: unknown[]) => {
        return new Promise((resolve) => {
          if (timeoutId) clearTimeout(timeoutId);

          timeoutId = setTimeout(async () => {
            resolve(await originalAction.apply(store, args));
          }, wait);
        });
      };
    });
  };
};
export default piniaDebounce;
